// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;
enum FishStatus{Free,Attract,RunAway,GiveUp}
@ccclass
export class FishController extends cc.Component {

    fishvec:cc.Vec2
    swimingSped:number
    river: cc.Node
    changeInveral:number
    hp:number
    status:FishStatus

    start () {
        console.log("Fish be created")
        this.fishvec = new cc.Vec2()
        this.swimingSped = 0.8
        this.hp = 100
        this.randomVector()
        this.changeStatus(FishStatus.Free)
    }

    private randomVector(){

        this.fishvec.x = -10 + Math.round(Math.random() * 20) > 0 ? 1 : -1;
        this.fishvec.y = -10 + Math.round(Math.random() * 20) > 0 ? 0.05 : -0.05;
        if(this.fishvec.x > 0)
        {
            this.turnRight()
        }
        else
        {
            this.turnLeft()
        }
        this.swimingSped = Math.round(Math.random()*30)/ 100+0.5
        this.changeInveral = 60.0
        // console.log("fishvec = ",this.fishvec.x,this.fishvec.y)
    }

    private turnRight() {
        this.node.setScale(cc.v2(-1, 1))
    }
    private turnLeft() {
        this.node.setScale(cc.v2(1, 1))
    }

    private revertVector()
    {
        // console.log("before revert fishvec = ", this.fishvec.x, this.fishvec.y)
        this.fishvec.x = 0 - this.fishvec.x
        this.fishvec.y = 0 - this.fishvec.y
        this.swimingSped = Math.round(Math.random() * 30) / 100 + 0.5
        if (this.fishvec.x > 0) 
        {
            this.turnRight()
        }
        else 
        {
            this.turnLeft()
        }
        console.log("revertVector fishvec = ", this.fishvec.x, this.fishvec.y)
    }
    
    private checkBorder():boolean{
        if(this.river == null){
            return true
        }
        // let riverBox = this.river.getBoundingBox()
        // riverBox.x
        // riverBox.width *= 0.9
        // riverBox.height *= 0.9
        // let fishBox = this.node.getBoundingBox()

        // return riverBox.containsRect(fishBox)
        let posx = this.node.position.x
        let posy = this.node.position.y
        if (posx <= 0 - this.node.width || posx >= this.river.width + this.node.width ){
            return true
        }
        if (posy <= 0 -this.node.height || posy >= this.river.height - this.node.height){
            return true
        }
        return false
    }
    
    private move(){
        let curPos = this.node.getPosition()
        curPos.x += this.fishvec.x * this.swimingSped
        curPos.y += this.fishvec.y * this.swimingSped
        // console.log("curPos = ", curPos)
        this.node.setPosition(curPos)
    }

    private changeStatus(newStatus:FishStatus){
        if (this.status === newStatus)
        {
            return
        }
        console.log("fish change status from ",this.status," to ",newStatus)
        this.status = newStatus
    }

    private freelySwimming(dt:number):void{
        if (this.changeInveral <= 0) {
            this.randomVector()
        }
        this.changeInveral -= dt

        if (!this.checkBorder()) {
            this.move()
        }
        else 
        {
            // console.log("reach edge")
            //碰到边缘了,知道，哪条边，然后计算出远离的相反方向走
            this.revertVector()
            this.move()
        }
    }

    public DoUpdate(dt:number):void{
        switch (this.status) {
            case FishStatus.Free:
                this.freelySwimming(dt)
                break;
            case FishStatus.Attract:
                //被鱼饵吸引了
                // console.log("被鱼饵吸引了")
                this.move()
                // console.log("attract position ",this.node.position)
                break;
            case FishStatus.RunAway:
                //逃跑
                this.move()
                console.log("fish vec = ",this.fishvec)
                console.log("fish runaway pos = ",this.node.position)
                break
            case FishStatus.GiveUp:
                this.swimingSped = 0.0
                this.fishvec.x = 0
                this.fishvec.y = 0
                this.node.angle = 90
                break
            default:
                break;
        }
        
    }

    //鱼被拉回
    public dragBack(){
        let revx = 0 - this.fishvec.x
        this.node.position.x += revx * 3
    }

    public IsGiveUp():boolean{
        let gg = this.hp <= 0
        if(gg)
        {
            this.changeStatus(FishStatus.GiveUp)
        }
        return gg
    }

    public BeAttacked(hit:number){
        this.hp -= hit
        this.dragBack()
    }

    public GetWorldBox():cc.Rect{
        return this.node.getBoundingBoxToWorld()
    }

    convertToNodePos(node: cc.Node, toNode: cc.Node): cc.Vec2 {
        return toNode.convertToNodeSpaceAR(node.convertToWorldSpaceAR(cc.v2(0, 0)));
    }

    public BeAttract(hook:cc.Node){
        let pb = this.convertToNodePos(hook,this.river)
        //计算方向
        this.fishvec.x = pb.x - this.node.position.x
        this.fishvec.y = pb.y - this.node.position.y
        this.fishvec.normalizeSelf()
        // console.log("fishvec = ",this.fishvec)
        //加速游向鱼饵
        this.swimingSped *= 2
        if (pb.x > this.node.position.x)
        {
            this.turnRight()
        }
        else
        {
            this.turnLeft()   
        }
        this.changeStatus(FishStatus.Attract)
    }

    //鱼上钩后开始逃跑
    public RunAway():void{
        this.fishvec.x = 1
        this.fishvec.y = 0
        console.log("runaway fishvec = ",this.fishvec)
        this.swimingSped = 0.05
        this.changeStatus(FishStatus.RunAway)
    }

    public GiveUp(hook:cc.Node):void{
        this.node.removeFromParent(false)
        this.node.setPosition(cc.v2(0, 0))
        hook.addChild(this.node)
    }

    public SetRiver(node:cc.Node):void{
        this.river = node
        this.river.addChild(this.node)

        let box = this.river.getBoundingBox()
        let posx = box.width*0.2 + Math.round(Math.random()*box.width*0.5)
        let posy = box.height*0.2 + Math.round(Math.random()*box.height*0.5)
        this.node.setPosition(posx,posy)
        // console.log("random position ",posx,posy)
    }
}
